package org.jeecg.modules.charge.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.StringUtils;
import org.jeecg.entity.charge.ChargeBills;
import org.jeecg.entity.charge.ChargeFeeitem;
import org.jeecg.entity.charge.ChargeInvoice;
import org.jeecg.entity.charge.ChargeInvoiceInfo;
import org.jeecg.entity.charge.ChargeInvoiceRequest;
import org.jeecg.enums.InvoiceTypeEnum;
import org.jeecg.modules.charge.entity.*;
import org.jeecg.modules.charge.entity.BwInvoiceEntity.*;
import org.jeecg.modules.charge.mapper.ComConfigMapper;
import org.jeecg.modules.charge.service.*;
import org.jeecg.modules.charge.service.impl.ChargeEleinvoiceServiceImpl;
import org.jeecg.modules.charge.service.impl.ChargeInvoiceRequestServiceImpl;
import org.jeecg.modules.charge.vo.BwInvoiceUtils.RequestUtils;
import org.jeecg.modules.charge.vo.BwInvoiceUtils.Utils;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.service.impl.SysDepartServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSONObject;
import com.baiwang.utility.encrypt.MyAES;


import sun.misc.BASE64Encoder;

/**
 * @author 作者Litao:
 * @version 创建时间：2019年9月16日 下午2:11:43 百望发票开具接口
 */
@Slf4j
@Api(tags="APP开票接口")
@RestController
@RequestMapping(value = "/b/charge/makeinvoice")
public class CharegeAppBwInvoiceController {
	/** SLF4J日志 */
	protected static final Logger logger = LoggerFactory.getLogger(CharegeAppBwInvoiceController.class);
	@Value("${bw.url}")
	private String bwinvoiceUrl;
	@Autowired
	private ChargeEleinvoiceServiceImpl eleInvoiceService;
	@Autowired
	private ChargeInvoiceRequestServiceImpl invoiceReqService;
	@Autowired
	private IChargeInvoiceInfoService invoiceInfoService;
	@Autowired
	private IChargeInvoiceService invoiceService;
	@Autowired
	private IChargeFeeitemService feeItemService;
	@Autowired
	private IChargeBillsService chargeBillsService;
	@Autowired
	private SysDepartServiceImpl sysDepartServiceImpl;
	@Autowired
	private ComConfigMapper comConfigMapper;

	/**
	 * 查询对应的缴费类型
	 *
	 *
	 */
	@AutoLog(value = "APP开具蓝票接口")
	@ApiOperation(value="APP开具蓝票接口", notes="APP开具蓝票接口")
	@PostMapping(value = "openblue")
	@ResponseBody
	public Result<Integer> openBlue(@RequestBody String req,HttpServletRequest request, HttpServletResponse response) throws Exception {
		StringBuffer sb = new StringBuffer("");
		String blueUrl = bwinvoiceUrl + "invoice";
		// 支付回调时需要根据判断对应分公司的配置来判断是否开具百望或者航信
		Date startDate = new Date();// 初始化开始时间
		SimpleDateFormat smf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//转化对应开票格式化日期
		SimpleDateFormat kpsmf = new SimpleDateFormat("yyyyMMddHHmmss");
		String now = smf.format(startDate);
		// InvoiceReqDeail 作为请求开票时插入到数据库中的对象 BlueInvoice 作为开票的对象去请求开票
		// BlueInvoiceDetailed作为开票的下级详情
		ChargeInvoiceRequest invoiceReqDeail = JSONObject.parseObject(req, ChargeInvoiceRequest.class);
		// ChargeBillsOrder
		// order=elecInvoiceService.getOrder(invoiceReqDeail.getOrderNum());
		request.setAttribute("tenantId",invoiceReqDeail.getTenantId());
		if (null != invoiceReqDeail.getOrderNum() && StringUtils.isNotEmpty(invoiceReqDeail.getOrderNum())) {
			String isExit = invoiceReqService.selectByOrderNum(invoiceReqDeail.getOrderNum());
			if (null != isExit && StringUtils.isNotEmpty(isExit)) {
				logger.info("订单号已存在");
				return Result.error("订单号已存在");
			}
		}
		invoiceReqDeail.setId(String.valueOf(IdWorker.getId()));
        invoiceReqDeail.setDelFlag("0");
		if (null == invoiceReqDeail.getRoomId() || StringUtils.isEmpty(invoiceReqDeail.getRoomId())) {
			logger.info("房间ID为空");
			return Result.error("房间ID为空");
		}
		String fpqqlsh = StringUtils.getRandomStringByLength(4) + DateUtils.detailStr(new Date());
		// 房间对应部门的id
	 	String projectId = invoiceReqService.getOidByRid(invoiceReqDeail.getRoomId(), "2");
		String oid = invoiceReqService.getOidByRid(invoiceReqDeail.getRoomId(), "1");
		// 获取公司ID
		SysDepart o = sysDepartServiceImpl.getCompanyByDepartId(oid);
		// 获取公司ID
		InvoiceBwConfig config = comConfigMapper.get(projectId);
		if(null==config) {
			logger.info("项目暂无对应的配置");
			return Result.error("项目暂无对应的配置");
		}
		String fhr = config.getFhr();
		// 开具蓝票，固定code为dfxj1001,临时存于filed1中
		config.setFiled1(Utils.dfxj1001);
		// 实体类转化为JSON
		JsonToBean jtb = new JsonToBean();
		jtb.getGlobalInfo().setAppId(config.getAppid());
		jtb.getGlobalInfo().setInterfaceCode(Utils.dfxj1001);
		jtb.getGlobalInfo().setRequestTime(now);
		// 数据交换流水号
		String dataExchangeId = "DZFPQZ" + Utils.dfxj1001 + Utils.formatToDay() + Utils.randNineData();
		jtb.getGlobalInfo().setDataExchangeId(dataExchangeId);
		// 请求开票的JSON
		JsonRootBean jrb = new JsonRootBean();
		REQUEST_COMMON_FPKJ fpkj = new REQUEST_COMMON_FPKJ();
		String tel = "";
		String address = "";
		fpkj.setFPQQLSH(fpqqlsh);
		fpkj.setKPLX("0");// 0蓝票，1红票
		fpkj.setXSF_NSRSBH(config.getXsfNsrsbh());
		fpkj.setXSF_MC(config.getXsfMc());
		fpkj.setXSF_DZDH(config.getXsfDzdh());
		if(null!=config.getXsfYhzh() && StringUtils.isNotEmpty(config.getXsfYhzh())) {
		fpkj.setXSF_YHZH(config.getXsfYhzh());	
		}
		if (null != invoiceReqDeail.getEin() && StringUtils.isNotEmpty(invoiceReqDeail.getEin())) {
			// 税号前端会有空格
			String ein = invoiceReqDeail.getEin().replaceAll(" ", "");
			fpkj.setGMF_NSRSBH(ein);
		}
		if (null != invoiceReqDeail.getTel() && StringUtils.isNotEmpty(invoiceReqDeail.getTel())) {
			if(this.isPhone(tel)) {
			fpkj.setGMF_SJH(invoiceReqDeail.getTel());
			}
			tel = invoiceReqDeail.getTel();	
		}
		if (null != invoiceReqDeail.getEmail() && StringUtils.isNotEmpty(invoiceReqDeail.getEmail())) {
			String email=invoiceReqDeail.getEmail().replaceAll(" ", "");
			if(this.isEmail(email)) {
				fpkj.setGMF_DZYX(invoiceReqDeail.getEmail());	
			}			
		}
		if (null != invoiceReqDeail.getAccount() && StringUtils.isNotEmpty(invoiceReqDeail.getAccount())) {
			fpkj.setGMF_YHZH(invoiceReqDeail.getAccount());
		}
		if (null != invoiceReqDeail.getAddress() && StringUtils.isNotEmpty(invoiceReqDeail.getAddress())) {
			address = invoiceReqDeail.getAddress();
		}
		fpkj.setGMF_DZDH(address + " " + tel);
		fpkj.setGMF_MC(invoiceReqDeail.getGmfMc());
		// 临时存于开票人
		fpkj.setKPR(config.getKpr());
		if(null!=fhr && StringUtils.isNotEmpty(fhr)) {
			fpkj.setFHR(fhr);
		}		
		fpkj.setSKR(config.getKpr());
		Double jshj = invoiceReqDeail.getMoney();
		Double hjje = 0.00;
		Double hjse = 0.00;
		// 用于项目的金额合计
		Double xmhjje = 0.00;
		Double xmsl=null;
		String subCode=null;
		fpkj.setJSHJ(String.valueOf(jshj));
		invoiceReqDeail.setInvoiceStatus("2");// 默认为开票中
		invoiceReqDeail.setFpqqlsh(fpqqlsh);
		invoiceReqDeail.setMoney(invoiceReqDeail.getMoney());
		invoiceReqDeail.setComId(o.getId());
		String roomId=null;
		String zhid =null;
		//用于区分线上线下，线上没有传对应业主ID，null则是线上
		if (null == invoiceReqDeail || StringUtils.isEmpty(invoiceReqDeail.getCustomerId())) {
			roomId=invoiceReqDeail.getRoomId();
			zhid=invoiceReqService.getOidByRid(roomId, "3");
			invoiceReqDeail.setCustomerId(zhid);
		}
		//线下请求
		else {
			roomId=eleInvoiceService.getRoomIdByCid(invoiceReqDeail.getCustomerId());
		}
		// 房间对应项目的ID
		String pid = invoiceReqService.getOidByRid(roomId, "2");

		String adress = invoiceReqService.getOidByRid(roomId, "5");
		invoiceReqDeail.setProjectId(pid);
		invoiceReqDeail.setReqUrl(blueUrl);
//		if(null==invoiceReqDeail.getPayMethod()) {
//			invoiceReqDeail.setPayMethod();
//		}
		String subMethod=invoiceReqService.getSubCodeByMethod(invoiceReqDeail.getPayMethod().toString());
		// 默认为开票成功
		invoiceReqDeail.setRemarks("请求支付,开票中!");
		invoiceReqDeail.setFiled6(config.getKpr());
		// 拼接开票地址
		String billids = (String)invoiceReqDeail.getBillIds();
		List<BlueInvoiceDetailed> blueInvoiceList = new ArrayList<BlueInvoiceDetailed>(); //电子发票的详情集合
		if (null != billids && StringUtils.isNotEmpty(billids)) {
			logger.info("账单ID为空");
		List<String> bids = new ArrayList<String>();
		// 如果是日常收费，会有对应的账单ID
		String str[] = billids.split(",");
		for (int i = 0; i < str.length; i++) {
			bids.add(str[i]);
		}
		if (null == bids || bids.size() == 0) {
			logger.info("新拼接账单为空!");
			return Result.error("新拼接账单为空!");
		}
		String bz = "";
		// 拼接开票详情
		List<COMMON_FPKJ_XMXX> details = new ArrayList<COMMON_FPKJ_XMXX>();
		List<ChargeBills> bills = chargeBillsService.listByBills(bids);
		if(bills.size() > 0 ){
			xmsl=bills.get(0).getTaxRate()/100;
		}
		for (int i = 0; i < bills.size(); i++) {
			bz = bills.get(0).getZjCny() + ">" + bills.get(bills.size() - 1).getZjCny();
		}
		if (null != adress && StringUtils.isNotEmpty(adress)) {
			bz = bz + "\n" + adress;
		}
		fpkj.setBZ(bz);
		List<ChargeBills> newbills = new ArrayList<ChargeBills>();
		if (null != bills && bills.size() > 0) {
			for (ChargeBills bill : bills) {
				boolean flag = false;
				// 用于存放对应的摘要
				List<String> zys = new ArrayList<String>();
				String cny = bill.getZjCny();
				// 循环遍历查询相同的收费项目下，相同的金额下拼接成请求详细参数
				for (ChargeBills b : newbills) {
					if (bill.getFeeitemId().equals(b.getFeeitemId()) && bill.getDue().compareTo(b.getDue()) == 0) {
						zys.add(b.getZjCny());
						cny += "," + b.getZjCny();
						b.setNum(b.getNum()+1);
						b.setZjCny(cny);
						flag = true;
					}
				}
				if (!flag) {
					newbills.add(bill);
				}
			}
			if (newbills.size() == 1) {
				for (ChargeBills b : newbills) {
					COMMON_FPKJ_XMXX detail = new COMMON_FPKJ_XMXX();
					if (null != b.getZjCny() || StringUtils.isEmpty(b.getZjCny())) {
						String cnys[] = b.getZjCny().split(",");
						String newcnys[] = StringUtils.buffSort(cnys);
						b.setZjCny(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
						detail.setBY1(b.getZjCny());
					}
					Double sl = b.getTaxRate() / 100;
					detail.setBY2(b.getFeeitemId());
					detail.setSL(String.valueOf(sl));
					detail.setXMSL(String.valueOf(b.getNum()));
					// 含税总金额
					Double jesum = 0.00;
					jesum = invoiceReqDeail.getMoney();
					// 不含税金额
					Double realjesum = new BigDecimal(jesum / (1 + Double.valueOf(detail.getSL())))
							.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
					// 税额
					Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
					// 临时存放税额
					b.setIncome(se);
					// 临时存放金额
					b.setHistoricalJe(jesum);
					// 不含税单价
					Double realdj = realjesum / Integer.valueOf(detail.getXMSL());
					detail.setXMMC(b.getFeeName());
					detail.setFPHXZ("0");
					// 临时存放商品编码
					detail.setSPBM(b.getMaintenanceCost());
					detail.setXMDJ(String.valueOf(realdj));
					hjse = se;
					/*
					 * Double xmjesum=new BigDecimal(jesum).setScale(2,
					 * BigDecimal.ROUND_HALF_UP).doubleValue();
					 */
					detail.setXMJE(String.valueOf(realjesum));
					detail.setSE(String.valueOf(se));
					details.add(detail);
					/*
					* 电子发票详情信息
					* */
					BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
					blueInvoice.setXmsl(b.getNum());
					blueInvoice.setFeeCode(b.getFeeitemId());
					blueInvoice.setSl(b.getTaxRate()/100);
					blueInvoice.setSubjectCode(b.getSubjectsCode());
					blueInvoice.setUnitprice(b.getDue().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
					blueInvoice.setXmjshj(new BigDecimal(jesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
					blueInvoice.setXmmc(b.getFeeName());
					blueInvoice.setZy(b.getZjCny());
					blueInvoiceList.add(blueInvoice);
				}
			}
			// 由于四舍五入会有对应的差异，则先轮训对应的金额，最后一个则用总的计税合计减去对应的金额
			else {
				for (int i = 0; i < newbills.size() - 1; i++) {
					COMMON_FPKJ_XMXX detail = new COMMON_FPKJ_XMXX();
					ChargeBills b = newbills.get(i);
					if (null != b.getZjCny() || StringUtils.isEmpty(b.getZjCny())) {
						String cnys[] = b.getZjCny().split(",");
						String newcnys[] = StringUtils.buffSort(cnys);
						b.setZjCny(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
						detail.setBY1(b.getZjCny());
					}
					Double sl = b.getTaxRate() / 100;
					detail.setBY2(b.getFeeitemId());
					detail.setSL(String.valueOf(sl));
					detail.setXMSL(String.valueOf(b.getNum()));
					// 含税总金额
					Double jesum = new BigDecimal(b.getNum()).multiply(b.getDue()).setScale(2, BigDecimal.ROUND_HALF_UP)
							.doubleValue();
					xmhjje += jesum;
					// 税额
					Double realjesum = new BigDecimal(jesum / (1 + Double.valueOf(detail.getSL())))
							.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
					// 计算出项目金额(不含税总金额)
					Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
					// 不含税单价
					Double realdj = realjesum / Integer.valueOf(detail.getXMSL());
					// 临时存放税额
					b.setIncome(se);
					// 临时存放金额
					b.setHistoricalJe(jesum);
					detail.setXMMC(b.getFeeName());
					detail.setFPHXZ("0");
					// 临时存放商品编码
					detail.setSPBM(b.getMaintenanceCost());
					detail.setXMDJ(String.valueOf(realdj));
					hjse += se;
					/*
					 * Double xmjesum=new BigDecimal(jesum).setScale(2,
					 * BigDecimal.ROUND_HALF_UP).doubleValue();
					 */
					detail.setXMJE(String.valueOf(realjesum));
					detail.setSE(String.valueOf(se));
					details.add(detail);
					/*
					 * 电子发票详情信息
					 * */
					BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
					blueInvoice.setXmsl(b.getNum());
					blueInvoice.setFeeCode(b.getFeeitemId());
					blueInvoice.setSl(b.getTaxRate()/100);
					blueInvoice.setSubjectCode(b.getSubjectsCode());
					blueInvoice.setUnitprice(b.getDue().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
					blueInvoice.setXmjshj(new BigDecimal(jesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
					blueInvoice.setXmmc(b.getFeeName());
					blueInvoice.setZy(b.getZjCny());
					blueInvoiceList.add(blueInvoice);
				}
				ChargeBills b = newbills.get(newbills.size() - 1);
				COMMON_FPKJ_XMXX detail = new COMMON_FPKJ_XMXX();
				if (null != b.getZjCny() || StringUtils.isEmpty(b.getZjCny())) {
					String cnys[] = b.getZjCny().split(",");
					String newcnys[] = StringUtils.buffSort(cnys);
					b.setZjCny(newcnys[0] + ">" + newcnys[newcnys.length - 1]);
					detail.setBY1(b.getZjCny());
				}
				Double sl = b.getTaxRate() / 100;
				detail.setBY2(b.getFeeitemId());
				detail.setSL(String.valueOf(sl));
				detail.setXMSL(String.valueOf(b.getNum()));
				// 含税总金额
				Double jesum = invoiceReqDeail.getMoney() - xmhjje;
				// 税额
				Double realjesum = new BigDecimal(jesum / (1 + Double.valueOf(detail.getSL())))
						.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
				// 计算出项目金额(不含税总金额)
				Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
				// 不含税单价
				Double realdj = realjesum / Integer.valueOf(detail.getXMSL());
				// 临时存放税额
				b.setIncome(se);
				// 临时存放金额
				b.setHistoricalJe(jesum);
				detail.setXMMC(b.getFeeName());
				detail.setFPHXZ("0");
				// 临时存放商品编码
				detail.setSPBM(b.getMaintenanceCost());
				detail.setXMDJ(String.valueOf(realdj));
				hjse += se;
				/*
				 * Double xmjesum=new BigDecimal(jesum).setScale(2,
				 * BigDecimal.ROUND_HALF_UP).doubleValue();
				 */
				detail.setXMJE(String.valueOf(realjesum));
				detail.setSE(String.valueOf(se));
				details.add(detail);
				/*
				 * 电子发票详情信息
				 * */
				BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
				blueInvoice.setXmsl(b.getNum());
				blueInvoice.setFeeCode(b.getFeeitemId());
				blueInvoice.setSl(b.getTaxRate()/100);
				blueInvoice.setSubjectCode(b.getSubjectsCode());
				blueInvoice.setUnitprice(b.getDue().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
				blueInvoice.setXmjshj(new BigDecimal(jesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
				blueInvoice.setXmmc(b.getFeeName());
				blueInvoice.setZy(b.getZjCny());
				blueInvoiceList.add(blueInvoice);
			}
			hjje = new BigDecimal(jshj - hjse).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			hjse= new BigDecimal(hjse).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			fpkj.setHJJE(String.valueOf(hjje));
			fpkj.setHJSE(String.valueOf(hjse));
			invoiceReqDeail.setHjje(hjje);
			invoiceReqDeail.setHjse(hjse);
			COMMON_FPKJ_XMXXS xmxxs = new COMMON_FPKJ_XMXXS();
			xmxxs.setCOMMON_FPKJ_XMXX(details);
			fpkj.setCOMMON_FPKJ_XMXXS(xmxxs);
			JSONObject jo = (JSONObject) JSONObject.toJSON(fpkj);
			String xmxxsStr = jo.toJSONString();
			xmxxsStr = "{\"REQUEST_COMMON_FPKJ\":" + xmxxsStr + "}";
			// 请求开票JSON转base64
			String oldbaseXmxxsStr = new BASE64Encoder().encodeBuffer(xmxxsStr.getBytes("UTF-8"));
			String baseXmxxsStr = oldbaseXmxxsStr.replaceAll("\r\n", "").replaceAll("\n", "").replaceAll("\r", "");
			String contentMD5 = MyAES.MD5(baseXmxxsStr.getBytes("UTF-8"));
			String contentKey = MyAES
					.encryptBASE64(MyAES.encrypt(contentMD5.getBytes("UTF-8"), config.getContentPassword()))
					.replaceAll("\r\n", "").replaceAll("\n", "").replace("\r", "");
			jtb.getData().setContent(baseXmxxsStr);
			jtb.getData().setContentKey(contentKey);
			jrb.setREQUEST_COMMON_FPKJ(fpkj);
			JSONObject reqJson = (JSONObject) JSONObject.toJSON(jtb);
			String joStr = reqJson.toJSONString();
			sb.append("{");
			sb.append("\"interface\":");
			sb.append(joStr);
			sb.append("}");
			String requestData = sb.toString();
			// 请求信息
			invoiceReqDeail.setReq(requestData);
			// 判断是否需要封账
			if (null != config.getFiled2() && StringUtils.isNotEmpty(config.getFiled2())) {
				Integer sealDate = Integer.valueOf(config.getFiled2());
				// 将开票状态改为5，表示封账待开的账单，在次月1号轮训开具。不进行请求
				Integer dd = DateUtils.getDayByDate(now);
				if (dd > sealDate) {
					String newdate = DateUtils.getFirstDay(now);
					invoiceReqDeail.setInvoiceStatus("0");
					invoiceReqDeail.setRemarks("封账待开!");
					invoiceReqDeail.setMakeInvoiceDate(smf.parse(newdate));
					// 封账日
					eleInvoiceService.insertInvoiceReq(invoiceReqDeail);
					return Result.ok("封账待开");
				}
			}
			// 调用接口
			String rsData = RequestUtils.getHttpConnectResult(requestData, blueUrl);
			// 响应
			invoiceReqDeail.setRes(rsData);
			JSONObject reJson = JSONObject.parseObject(rsData);
			// 获取对应的相应信息
			String rsJson = reJson.get("interface").toString();
			// 响应信息转为实体类
			JsonToBean resEntity = JSONObject.parseObject(rsJson, JsonToBean.class);
			String resCode = resEntity.getReturnStateInfo().getReturnCode();

			// 表示开票成功
			if ("0000".equals(resCode)) {
				String resContent = resEntity.getData().getContent();
				byte[] asBytes = Base64.getDecoder().decode(resContent);
				String jsonContent = new String(asBytes, "UTF-8");
				ResContent responseContent = JSONObject.parseObject(jsonContent, ResContent.class);
				// 临时存放发票的PDF地址
				invoiceReqDeail.setPdfUrl(responseContent.getPDF_URL());
				invoiceReqDeail.setInvoiceStatus("1");
				invoiceReqDeail.setRemarks("开票成功!");
				invoiceReqDeail.setFpdm(responseContent.getFP_DM());
				invoiceReqDeail.setFphm(responseContent.getFP_HM());
				invoiceReqDeail.setKprq(responseContent.getKPRQ());
				invoiceReqDeail.setMakeInvoiceDate(kpsmf.parse(responseContent.getKPRQ()));
				invoiceReqDeail.setFiled4(String.valueOf(xmsl));
				invoiceReqDeail.setFiled5(subCode);
				//用作凭证作成
				VoucherProject voucher = comConfigMapper.getVoucherConfig(projectId,roomId);
				if(null != voucher){
					invoiceReqDeail.setVoucherItem(voucher.getVoucherItem());
					invoiceReqDeail.setVoucherCompany(voucher.getComName());
				}
				Integer reqresult =eleInvoiceService.insertInvoiceReq(invoiceReqDeail);
				try{
					if(reqresult > 0){
						for(BlueInvoiceDetailed detail:blueInvoiceList) {
							BigDecimal big = new BigDecimal(detail.getXmjshj()/(1+detail.getSl()));
							Double income=big.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
							Double tax=detail.getXmjshj()-income;
							detail.setIncome(income);
							detail.setTax(tax);
							detail.setInvoiceRequestId(invoiceReqDeail.getId());
							detail.setId(String.valueOf(IdWorker.getId()));
							invoiceReqService.addRequestInfo(detail);
						}
					}
				}catch (Exception e){
					log.error(e.getMessage(), e);
					logger.info("电票详情插入异常！");
					return Result.error("电票详情插入异常！");
				}
				if (reqresult > 0) {
					// 更新对应账单并更新发票信息
					ChargeBills u = new ChargeBills();
					u.setInvoiceNo(responseContent.getFP_HM());
					u.setInvoiceGrnno(responseContent.getFP_DM());
					u.setPayType(invoiceReqDeail.getPayMethod());
					u.setZjSkrq(kpsmf.parse(responseContent.getKPRQ()));
					//临时存放对应的PDF地址
					u.setDateRange(responseContent.getPDF_URL());
					u.setPayuserName(config.getKpr());
					u.setMakeinvoiceDate(kpsmf.parse(responseContent.getKPRQ()));
					u.setBillIds(bids);
					eleInvoiceService.updateBillsInvoice(u);
					// 插入票据和票据信息表中
					ChargeInvoice invoice = new ChargeInvoice();
					invoice.setProjectId(invoiceReqDeail.getProjectId());
					invoice.setInvoiceHm(invoiceReqDeail.getFphm());
					invoice.setInvoiceDm(invoiceReqDeail.getFpdm());
					invoice.setMakeInvoiceDate(kpsmf.parse(invoiceReqDeail.getKprq()));
					invoice.setPayer(invoiceReqDeail.getGmfMc());
					invoice.setMoney(invoiceReqDeail.getMoney());
					invoice.setZjSkrq(new SimpleDateFormat("yyyyMMddHHmmss").parse(invoiceReqDeail.getKprq()));
					invoice.setPayMethod(invoiceReqDeail.getPayMethod());
					invoice.setInvoiceMan(config.getKpr());
					invoice.setPayee(config.getKpr());
					invoice.setAddress(invoiceReqDeail.getAddress());
					invoice.setCustomerId(invoiceReqDeail.getCustomerId());
					invoice.setPdfUrl((String)invoiceReqDeail.getPdfUrl());
					invoice.setDelFlag("0");
					// 表示电子发票
					invoice.setTicket(InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode());
					String pjid;
					// 插入前查询此发票号码和代码是否存在，存在不给继续插入
					String fpcount = invoiceService.getIdByInvoice(invoiceReqDeail.getFphm(), invoiceReqDeail.getFpdm());
					if (null==fpcount) {
						Boolean re = invoiceService.save(invoice);
						// 插入成功
						if (re) {
							pjid = invoice.getId();
							System.out.println("票据ID为:" + pjid);
							List<ChargeInvoiceInfo> infos = new ArrayList<ChargeInvoiceInfo>();
							// 循环创建对应开票信息
							for (COMMON_FPKJ_XMXX xmxx : details) {
								ChargeInvoiceInfo info = new ChargeInvoiceInfo();
								info.setId(String.valueOf(IdWorker.getId()));
								info.setInvoiceId(pjid);
								info.setInvoiceDm(invoiceReqDeail.getFpdm());
								info.setInvoiceHm(invoiceReqDeail.getFphm());
								info.setAbstractInfo(xmxx.getBY1());
								info.setAddress(invoiceReqDeail.getAddress());
								info.setInvoiceObject(xmxx.getXMMC());
								info.setNum(Integer.valueOf(xmxx.getXMSL()));
								info.setUnitPrice(Double.valueOf(xmxx.getXMDJ()));
								info.setMoney(Double.valueOf(xmxx.getSE()) + Double.valueOf(xmxx.getXMJE()));
								info.setSubjectCode(xmxx.getXMMC());
								info.setFeeitemId(xmxx.getBY2());
								info.setRate(Double.valueOf(xmxx.getSL()));
								info.setTax(Double.valueOf(xmxx.getSE()));
								info.setRealMoney(Double.valueOf(xmxx.getXMJE()));
								info.setDelFlag("0");
								infos.add(info);
							}
							invoiceInfoService.insertInfos(infos);
						} else {
							logger.info("发票请求为空!");
							return Result.ok("发票请求为空!");
						}
					}
					// 重复票据
					else {
						invoiceReqDeail.setInvoiceStatus("3");
						invoiceReqDeail.setRemarks("轮训查询,票据已经插入!");
						invoiceReqService.updateById(invoiceReqDeail);
						return Result.ok("轮训查询,票据已经插入!");
					}
				}
			} else {
				invoiceReqDeail.setInvoiceStatus("3");
				invoiceReqDeail.setRemarks("开票失败!");
				eleInvoiceService.insertInvoiceReq(invoiceReqDeail);
				return Result.ok("开票失败");
			}
		}
	
		}
		//无账单电费开票
		else {
			// 拼接开票详情
			List<COMMON_FPKJ_XMXX> details = new ArrayList<COMMON_FPKJ_XMXX>();
			COMMON_FPKJ_XMXX detail = new COMMON_FPKJ_XMXX();
			//存放于对应的收费项目编号
			String feecode=invoiceReqDeail.getFiled5();
			ChargeFeeitem item=feeItemService.getFeeitemByCode(feecode);
			Double rate=(double)eleInvoiceService.getRateByRoomFeeCode(roomId, feecode);
			if(null==rate) {
				System.out.println("暂无税率");
				return null;
			}
						Double sl =rate / 100;
						detail.setBY2(feecode);
						detail.setSL(String.valueOf(sl));
						detail.setXMSL("1");
						// 含税总金额
						Double jesum = 0.00;
						jesum = invoiceReqDeail.getMoney();
						// 不含税金额
						Double realjesum = new BigDecimal(jesum / (1 + Double.valueOf(detail.getSL())))
								.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
						// 税额
						Double se = new BigDecimal(jesum - realjesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();				
						// 不含税单价
						Double realdj = realjesum / Integer.valueOf(detail.getXMSL());
						detail.setXMMC(item.getFeeName());
						detail.setFPHXZ("0");
						// 临时存放商品编码
						detail.setSPBM(item.getMaintenanceCost());
						detail.setXMDJ(String.valueOf(realdj));
						hjse = se;
						hjje=realdj;
						/*
						 * Double xmjesum=new BigDecimal(jesum).setScale(2,
						 * BigDecimal.ROUND_HALF_UP).doubleValue();
						 */
						detail.setXMJE(String.valueOf(realjesum));
						detail.setSE(String.valueOf(se));
						details.add(detail);
			/*
			 * 电子发票详情信息
			 * */
			BlueInvoiceDetailed blueInvoice=new BlueInvoiceDetailed();
			blueInvoice.setXmsl(1);
			blueInvoice.setFeeCode(item.getId());
			blueInvoice.setSl(sl);
			blueInvoice.setSubjectCode(item.getSubjectsCode());
			blueInvoice.setUnitprice(new BigDecimal(invoiceReqDeail.getMoney()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
			blueInvoice.setXmjshj(new BigDecimal(jesum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
			blueInvoice.setXmmc(item.getFeeName());

			fpkj.setBZ(adress);
			fpkj.setHJJE(String.valueOf(hjje));
			fpkj.setHJSE(String.valueOf(hjse));
			invoiceReqDeail.setHjje(hjje);
			invoiceReqDeail.setHjse(hjse);
			COMMON_FPKJ_XMXXS xmxxs = new COMMON_FPKJ_XMXXS();
			xmxxs.setCOMMON_FPKJ_XMXX(details);
			fpkj.setCOMMON_FPKJ_XMXXS(xmxxs);
			JSONObject jo = (JSONObject) JSONObject.toJSON(fpkj);
			String xmxxsStr = jo.toJSONString();
			xmxxsStr = "{\"REQUEST_COMMON_FPKJ\":" + xmxxsStr + "}";
			// 请求开票JSON转base64
			String oldbaseXmxxsStr = new BASE64Encoder().encodeBuffer(xmxxsStr.getBytes("UTF-8"));
			String baseXmxxsStr = oldbaseXmxxsStr.replaceAll("\r\n", "").replaceAll("\n", "").replaceAll("\r", "");
			String contentMD5 = MyAES.MD5(baseXmxxsStr.getBytes("UTF-8"));
			String contentKey = MyAES
					.encryptBASE64(MyAES.encrypt(contentMD5.getBytes("UTF-8"), config.getContentPassword()))
					.replaceAll("\r\n", "").replaceAll("\n", "").replace("\r", "");
			jtb.getData().setContent(baseXmxxsStr);
			jtb.getData().setContentKey(contentKey);
			jrb.setREQUEST_COMMON_FPKJ(fpkj);
			JSONObject reqJson = (JSONObject) JSONObject.toJSON(jtb);
			String joStr = reqJson.toJSONString();
			sb.append("{");
			sb.append("\"interface\":");
			sb.append(joStr);
			sb.append("}");
			String requestData = sb.toString();
			// 请求信息
			invoiceReqDeail.setReq(requestData);
			// 判断是否需要封账
			if (null != config.getFiled2() && StringUtils.isNotEmpty(config.getFiled2())) {
				Integer sealDate = Integer.valueOf(config.getFiled2());
				// 将开票状态改为5，表示封账待开的账单，在次月1号轮训开具。不进行请求
				Integer dd = DateUtils.getDayByDate(now);
				if (dd > sealDate) {
					String newdate = DateUtils.getFirstDay(now);
					invoiceReqDeail.setInvoiceStatus("0");
					invoiceReqDeail.setRemarks("封账待开!");
					invoiceReqDeail.setMakeInvoiceDate(smf.parse(newdate));
					// 封账日
					eleInvoiceService.insertInvoiceReq(invoiceReqDeail);
					return Result.ok("封账待开!");
				}
			}
			// 调用接口
			String rsData = RequestUtils.getHttpConnectResult(requestData, blueUrl);
			// 响应
			invoiceReqDeail.setRes(rsData);
			JSONObject reJson = JSONObject.parseObject(rsData);
			// 获取对应的相应信息
			String rsJson = reJson.get("interface").toString();
			// 响应信息转为实体类
			JsonToBean resEntity = JSONObject.parseObject(rsJson, JsonToBean.class);
			String resCode = resEntity.getReturnStateInfo().getReturnCode();

			// 表示开票成功
			if ("0000".equals(resCode)) {
				String resContent = resEntity.getData().getContent();
				byte[] asBytes = Base64.getDecoder().decode(resContent);
				String jsonContent = new String(asBytes, "UTF-8");
				ResContent responseContent = JSONObject.parseObject(jsonContent, ResContent.class);
				// 临时存放发票的PDF地址
				invoiceReqDeail.setPdfUrl(responseContent.getPDF_URL());
				invoiceReqDeail.setFpdm(responseContent.getFP_DM());
				invoiceReqDeail.setFphm(responseContent.getFP_HM());
				invoiceReqDeail.setKprq(responseContent.getKPRQ());
				invoiceReqDeail.setMakeInvoiceDate(kpsmf.parse(responseContent.getKPRQ()));
				invoiceReqDeail.setFiled4(String.valueOf(sl));
				invoiceReqDeail.setFiled5(item.getSubjectsCode());

				Integer reqresult = eleInvoiceService.insertInvoiceReq(invoiceReqDeail);
				try{
					if(reqresult > 0){
							BigDecimal big = new BigDecimal(blueInvoice.getXmjshj()/(1+blueInvoice.getSl()));
							Double income=big.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
							Double tax=blueInvoice.getXmjshj()-income;
							blueInvoice.setIncome(income);
							blueInvoice.setTax(tax);
							blueInvoice.setInvoiceRequestId(invoiceReqDeail.getId());
							blueInvoice.setId(String.valueOf(IdWorker.getId()));
							invoiceReqService.addRequestInfo(blueInvoice);
					}
				}catch (Exception e){
					log.error(e.getMessage(), e);
					logger.info("电票详情插入异常！");
					return Result.error("电票详情插入异常！");
				}


				if (reqresult > 0) {
					// 插入票据和票据信息表中
					ChargeInvoice invoice = new ChargeInvoice();
					invoice.setProjectId(invoiceReqDeail.getProjectId());
					invoice.setInvoiceHm(invoiceReqDeail.getFphm());
					invoice.setInvoiceDm(invoiceReqDeail.getFpdm());
					invoice.setMakeInvoiceDate(kpsmf.parse(invoiceReqDeail.getKprq()));
					invoice.setPayer(invoiceReqDeail.getGmfMc());
					invoice.setMoney(invoiceReqDeail.getMoney());
					invoice.setZjSkrq(new SimpleDateFormat("yyyyMMddHHmmss").parse(invoiceReqDeail.getKprq()));
					invoice.setPayMethod(invoiceReqDeail.getPayMethod());
					invoice.setInvoiceMan(config.getKpr());
					invoice.setPayee(config.getKpr());
					invoice.setAddress(invoiceReqDeail.getAddress());
					invoice.setCustomerId(invoiceReqDeail.getCustomerId());
					invoice.setPdfUrl((String)invoiceReqDeail.getPdfUrl());
					invoice.setDelFlag("0");
					// 表示电子发票
					invoice.setTicket(InvoiceTypeEnum.INVOICE_TYPE_ELE.getCode());
					String pjid;
					// 插入前查询此发票号码和代码是否存在，存在不给继续插入
					String  fpcount = invoiceService.getIdByInvoice(invoiceReqDeail.getFphm(),
							invoiceReqDeail.getFpdm());
					if (null==fpcount) {
						Boolean re = invoiceService.save(invoice);
						// 插入成功
						if (re) {
							pjid = invoice.getId();
							System.out.println("票据ID为:" + pjid);
							List<ChargeInvoiceInfo> infos = new ArrayList<ChargeInvoiceInfo>();
							// 循环创建对应开票信息
							for (COMMON_FPKJ_XMXX xmxx : details) {
								ChargeInvoiceInfo info = new ChargeInvoiceInfo();
                                info.setId(String.valueOf(IdWorker.getId()));
								info.setInvoiceId(pjid);
								info.setInvoiceDm(invoiceReqDeail.getFpdm());
								info.setInvoiceHm(invoiceReqDeail.getFphm());
								info.setAbstractInfo(xmxx.getBY1());
								info.setAddress(invoiceReqDeail.getAddress());
								info.setInvoiceObject(xmxx.getXMMC());
								info.setNum(Integer.valueOf(xmxx.getXMSL()));
								info.setUnitPrice(Double.valueOf(xmxx.getXMDJ()));
								info.setMoney(Double.valueOf(xmxx.getSE()) + Double.valueOf(xmxx.getXMJE()));
								info.setSubjectCode(xmxx.getXMMC());
								info.setFeeitemId(xmxx.getBY2());
								info.setRate(Double.valueOf(xmxx.getSL()));
								info.setTax(Double.valueOf(xmxx.getSE()));
								info.setRealMoney(Double.valueOf(xmxx.getXMJE()));
								info.setDelFlag("0");
								infos.add(info);
							}
							invoiceInfoService.insertInfos(infos);
						} else {

							logger.info("发票请求为空!");
							return null;
						}
					}
					// 重复票据
					else {
						invoiceReqDeail.setInvoiceStatus("3");
						invoiceReqDeail.setRemarks("轮训查询,票据已经插入!");
						invoiceReqService.updateById(invoiceReqDeail);
						return Result.ok("轮训查询,票据已经插入!");
					}
				}
			} else {
				invoiceReqDeail.setInvoiceStatus("3");
				invoiceReqDeail.setRemarks("开票失败!");
				eleInvoiceService.insertInvoiceReq(invoiceReqDeail);
				return Result.ok("开票失败!");
			}
		}
		return Result.ok("开票成功!");
	}

			//验证邮箱方法
			public static boolean isEmail(String string) {
				if (string == null)
					return false;
				String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
				Pattern p;
				Matcher m;
				p = Pattern.compile(regEx1);
				m = p.matcher(string);
				if (m.matches())
					return true;
				else
					return false;
			}
			//验证手机号码
			public static boolean isPhone(String phone) {
			    String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
			    if (phone.length() != 11) {
			        return false;
			    } else {
			        Pattern p = Pattern.compile(regex);
			        Matcher m = p.matcher(phone);
			        boolean isMatch = m.matches();
			        return isMatch;
			    }
			    }
	}
